home *** CD-ROM | disk | FTP | other *** search
/ A.C.E. 2 / ACE CD 2.iso / FILES / UTILS / PROCAL13.DMS / PROCAL13.adf / Rexx / replace.rexx < prev    next >
OS/2 REXX Batch file  |  1991-12-11  |  10KB  |  245 lines

  1. /* Replace                    S. Dicker                 8-Aug-89    */
  2. /*                                                                  */
  3. /*    ARexx program used to replace all occurrences of one string   */
  4. /*  with another in a selected range of cells. This program can be  */
  5. /*  used, for example, to modify all formulas that refer to cell C1 */
  6. /*  so that they refer to cell B1 instead. Select the range of      */
  7. /*  cells to be modified and then issue the command:                */
  8. /*                                                                  */
  9. /*           rx replace <oldtext> <newtext>                         */
  10. /*                                                                  */
  11. /*                where  <oldtext> is the original string           */
  12. /*                       <newtext> is the replacement string        */
  13. /*                                                                  */
  14. /*  NOTE: String comparison/replacement is done in upper case only. */
  15. /*                                                                  */
  16.  
  17. signal on error                 /* Trap host command errors. */
  18.  
  19. /* Explicitly say "parse arg", to avoid converting args to uppercase */
  20. parse arg old_text new_text           /* Retrieve command line arguments. */
  21.  
  22. address 'Advantage'             /* Send commands to Advantage. */
  23. options results                 /* Enable return of string results. */
  24.  
  25. /* If the required arguments are not supplied, display an error */
  26. /* message and then quit.                                       */
  27. if old_text = "" | new_text = "" then
  28.    do
  29.       'DrawMessage'
  30.        "Usage: rx replace <oldtext> <newtext>"
  31.        exit 10
  32.     end
  33.     
  34. new_text = strip(new_text,'L')  /* Strip leading blanks. */    
  35.     
  36. 'Current'                       /* Determine current selected range. */
  37. range = result
  38.  
  39. colon_posn = pos(":",range)     /* Look for colon delimiter in range. */
  40.  
  41. if colon_posn = 0 then          /* If no colon, this is not a range. */
  42.    do                           /*  Set the start and end cells to   */
  43.       start_cell = range        /*   the selected cell.              */
  44.       end_cell = range
  45.    end
  46. else                            /* Otherwise, it is a range. */
  47.    /* Extract the start/end cells from the specified range. */
  48.    do
  49.       start_cell = left(range,colon_posn - 1)
  50.       end_cell   = substr(range,colon_posn + 1)
  51.    end
  52.  
  53. start_column = GetColumn(start_cell)    /* Determine range of columns */
  54. end_column   = GetColumn(end_cell)      /*  to be filled.             */
  55.  
  56. start_row = GetRow(start_cell)          /* Determine range of rows */
  57. end_row   = GetRow(end_cell)            /*  to be filled.          */
  58.  
  59. /* Scan the selected range of cells for the string to be replaced. */
  60. /* It's much faster to scan in column-major order if possible,     */
  61. /* because NextColumn() is slower than just adding one to rownum.  */
  62.  
  63. /* Search all columns in the selected range. */
  64. column = start_column                /* Reset column pointer.  */
  65. do until c2d(column) > c2d(end_column)
  66.  
  67.    do rownum = start_row to end_row
  68.    
  69.       /* Build complete cell name from row and column. */
  70.       next_cell = column || rownum
  71.       /* Retrieve the current contents of this cell (if it contains */
  72.       /* a formula or label - values always return NULL).           */
  73.       contents = GetContents(next_cell)
  74.       /* Replace all occurrences of the search string. */
  75.       new_contents = Replace(contents,old_text,new_text)
  76.       /* If the string has changed, write it back to the cell. */
  77.       if new_contents ~= contents then
  78.          do
  79.             'SelectCell'
  80.                value(next_cell)
  81.             'PutCell'
  82.                new_contents
  83.          end
  84.    end
  85.    
  86.    /* Advance to the next column in this row. */
  87.    column = NextColumn(column)
  88. end
  89.       
  90. /* Reselect the original range of cells. */
  91. 'SelectRange'
  92.    value(start_cell)
  93.    value(end_cell)
  94.  
  95. exit                    /* That's all folks! */
  96.  
  97. /* >>> Host command error handler <<< */
  98. Error:
  99.    exit rc                 /* Just bail out and return error code. */
  100.  
  101.  
  102. /* ----------------------------------------------------------------- */
  103. /*            Internal Functions (subroutines)                       */
  104. /* ----------------------------------------------------------------- */
  105.  
  106. /* == GetRow: Extract the row number from a cell name. == */
  107.  
  108. GetRow: procedure
  109.    arg CellName      /* Function expects to be passed a cell name. */
  110.  
  111.    /* Find the first numeric digit in the cell name. */
  112.    start_number = verify(CellName,"0123456789","Match")
  113.    
  114.    /* Extract all characters starting at the first digit and continuing */
  115.    /* to the end of the cell name.                                      */
  116.    rownum = substr(CellName,start_number)
  117.  
  118. return rownum
  119.  
  120. /* == GetColumn: Extract the column label from a cell name. == */
  121.  
  122. GetColumn: procedure
  123.    arg CellName      /* Function expects to be passed a cell name. */
  124.  
  125.    /* Find the first numeric digit in the cell name. */
  126.    start_number = verify(CellName,"0123456789","Match")
  127.    
  128.    /* Extract all characters in the cell name up to the first numeric */
  129.    /* character (start of row number).                                */
  130.    column = left(CellName,start_number-1)
  131.  
  132. return column
  133.  
  134. /* == NextColumn: Given the current column label, determine the label == */
  135. /* ==              for the next sequential column. NOTE: This is a    == */
  136. /* ==              recursive function.                                == */
  137.  
  138. NextColumn: procedure
  139.    arg ThisColumn    /* Function expects to be passed a column label. */
  140.  
  141.    /* If the column label is empty (null string), then we must be */
  142.    /* starting a new group of column labels (for example, going   */
  143.    /* from column ZZ to column AAA. Return an "A".                */
  144.    if length(ThisColumn) = 0 then
  145.       new_column = "A"
  146.    
  147.    /* Otherwise, we must advance the last character in the column */
  148.    /* name to the next sequential alphabetic character.           */
  149.    else
  150.       do
  151.          col_number = ,                 /* Convert last character */
  152.             c2d( right(ThisColumn,1) )  /*  to decimal value.     */
  153.    
  154.          col_number = col_number + 1    /* Increment to next character. */
  155.          new_char = d2c(col_number)     /* Convert back to a character. */
  156.    
  157.          /* If we've gone past 'Z', find the next column for the column */
  158.          /* label minus the last character and then append an "A" to    */
  159.          /* this label (start of a new label set).                      */
  160.          if new_char > "Z" then
  161.             do
  162.                temp_column = left( ThisColumn, length(ThisColumn)-1 )
  163.                new_column = NextColumn(temp_column) || "A"
  164.             end
  165.          
  166.          /* Otherwise, replace the last character of the column label */
  167.          /* with the next sequential character.                       */
  168.          else
  169.             new_column = overlay(new_char,ThisColumn,length(ThisColumn))
  170.       end
  171.  
  172. return new_column
  173.  
  174. /* == GetContents: Extract the contents of a specified cell. == */
  175. /* ==              If the cell contains a "value" return a   == */
  176. /* ==              null (empty) string.                      == */
  177.  
  178. GetContents: procedure
  179.    arg CellName      /* Function expects to be passed a cell name. */
  180.  
  181.    'SelectCell'      /* Select the cell whose contents we want. */
  182.       value(CellName)
  183.       
  184.    'IsLabel'         /* Does this cell contain a "label". */
  185.    lab_flag = result
  186.    
  187.    'IsFormula'       /* Does this cell contain a "formula". */
  188.    form_flag = result
  189.  
  190.    /* Now extract the cell contents based on what type of data it  */
  191.    /* contains.                                                    */
  192.    select
  193.       when form_flag = 1 then           /* A Formula ...   */
  194.          do
  195.             'GetFormula'
  196.             cell_contents = result
  197.          end
  198.       when lab_flag = 1 then            /* ... a Label ... */
  199.          do
  200.             'GetLabel'
  201.             cell_contents = result
  202.          end
  203.       otherwise                         /* ... or a Value. */
  204.          cell_contents = ""
  205.    end
  206.  
  207. return cell_contents    /* Return the cell contents. */
  208.  
  209. /* == Replace: Replace all occurrences of oldstring with newstring == */
  210. /* ==           in the supplied string.                            == */
  211.  
  212. Replace: procedure
  213.    /* Explicitly say "parse arg", to avoid converting it all to uppercase */
  214.    parse arg start_string, oldstring, newstring
  215.  
  216.    upper oldstring            /* We want case-independent search */
  217.    start_pos = 1                        /* Where to begin next search.   */
  218.    
  219.    /* Repeat the search/replace process until we reach the end of the string. */
  220.    do until start_pos > length(start_string) | start_pos = 0
  221.  
  222.       upper_text = upper(start_string)  /* Convert string to upper case  */
  223.                                         /*  for case independent search. */
  224.       
  225.       /* Look for the string to be replaced. */
  226.       start_pos = pos(oldstring,upper_text,start_pos)
  227.       
  228.       /* If we find it, replace it. */
  229.       if start_pos ~= 0 then
  230.          do
  231.             /* Remove the old text. */
  232.             start_string =,
  233.                delstr( start_string, start_pos, length(oldstring) )
  234.             /* Insert the new text. */
  235.             start_string =,
  236.                insert( newstring, start_string, start_pos-1 )
  237.             /* Update location for start of next search to past */
  238.             /* the end of the replacement text.                 */
  239.             start_pos = start_pos + length(newstring)
  240.          end
  241.       
  242.    end
  243.    
  244. return start_string
  245.